package com.snail.monitor;

import com.sun.jna.examples.win32.Kernel32;
import com.sun.jna.examples.win32.User32;
import com.sun.jna.examples.win32.User32.HHOOK;
import com.sun.jna.examples.win32.User32.MSG;
import com.sun.jna.examples.win32.W32API.HMODULE;
import com.sun.jna.examples.win32.W32API.LRESULT;
import com.sun.jna.examples.win32.W32API.WPARAM;

public class MouseMonitor extends Thread {

    public static final int WM_MOUSEMOVE = 512;

    public static final int WM_LBUTTONUP = 514;

    public static final int WM_LBUTTONDOWN = 513;

    public static final int WM_RBUTTONUP = 517;

    public static final int WM_RBUTTONDOWN = 516;

    public static final int WM_MOUSEHWHEEL = 526;

    public static final int WM_MOUSEWHEEL = 522;

    private static HHOOK hhk;
    private static LowLevelMouseProc mouseHook;
    final static User32 lib = User32.INSTANCE;

    private boolean running = true;

    private MonitorRecord record;

    public MouseMonitor(boolean running, MonitorRecord record) {

        setRunning(running);
        setRecord(record);
    }

    public void run() {

        HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
        mouseHook = new LowLevelMouseProc() {

            public LRESULT callback(int nCode, WPARAM wParam, MouseHookStruct info) {

                if (!isRunning()) {
                    return null;
                }
                if (nCode >= 0) {
                    switch (wParam.intValue()) {
                        case MouseMonitor.WM_LBUTTONDOWN:
                            getRecord().leftDown(info.pt.x, info.pt.y);
                            break;
                        case MouseMonitor.WM_RBUTTONDOWN:
                            getRecord().rightDown(info.pt.x, info.pt.y);
                            break;
                    }
                }
                return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
            }
        };
        hhk = lib.SetWindowsHookEx(User32.WH_MOUSE_LL, mouseHook, hMod, 0);
        int result;
        MSG msg = new MSG();
        while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
            if (result == -1) {
                System.err.println("error in get message");
                break;
            } else {
                System.err.println("got message");
                lib.TranslateMessage(msg);
                lib.DispatchMessage(msg);
            }
        }
        lib.UnhookWindowsHookEx(hhk);
    }

    public boolean isRunning() {

        return running;
    }

    public void setRunning(boolean running) {

        this.running = running;
    }

    public MonitorRecord getRecord() {

        return record;
    }

    public void setRecord(MonitorRecord record) {

        this.record = record;
    }
}
